// generated 2005/6/29 18:27:49 CST by xihels@163.com
//


#if defined __GNUC__ && __GNUC__ < 3
#error This program will crash if compiled with g++ 2.x
// see the dynamic_cast bug in the gtkmm FAQ
#endif //
#include "config.h"
#include <gtkmmconfig.h>
#if GTKMM_MAJOR_VERSION==2 && GTKMM_MINOR_VERSION>2
#define GMM_GTKMM_22_24(a,b) b
#else //gtkmm 2.2
#define GMM_GTKMM_22_24(a,b) a
#endif //
#include <gdk/gdkkeysyms.h>
#include <gtkmm/accelgroup.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>
#include <gtkmm/button.h>
#include <gtkmm/box.h>
#include <gtkmm/stockid.h>
#include "config.h"
#include "MsgWindow.h"
#include "FriendInfo.h"
#include "ClusterInfo.h"
#include "QQSession.h"
#include "pixmaps.h"
#include <gdk/gdkkeysyms.h>
#include <assert.h>
//extern CodeConverter g2u;
MsgWindow::MsgWindow(QQSession& _session, BuddyInfo& buddyInfo) :
    session(_session)
{
    class Gtk::Window * msgWindow = this;
    gmm_data = new GlademmData(get_accel_group());

    notebookMsg = Gtk::manage(new class Gtk::Notebook());
    notebookMsg->unset_flags(Gtk::CAN_FOCUS);
    notebookMsg->set_scrollable(true);
    commandBar = Gtk::manage(new class CommandBar(this, gmm_data));

    Gtk::VBox* vboxArea = Gtk::manage(new class Gtk::VBox(false, 0));

    vboxArea->pack_start(*notebookMsg);
    vboxArea->pack_start(*commandBar, Gtk::PACK_SHRINK, 0);

    char idtext[16];
    snprintf(idtext, 16, "%d", _session.getUid());
    msgWindow->set_title(idtext);
    msgWindow->set_default_size(500,400);

    msgWindow->add(*vboxArea);

    showPage(buddyInfo, true);
    msgWindow->show_all();

    MsgPage* page = static_cast<MsgPage*>(notebookMsg->get_current()->get_child());
    set_focus(*(page->getFocusWidget()));
}

MsgWindow::~MsgWindow()
{
    delete gmm_data;
}

int MsgWindow::addPage(Glib::RefPtr<Gdk::Pixbuf> face, 
	const string& title, MsgPage* page)
{

    Gtk::Image *imageTabHeader = 
	Gtk::manage(new class Gtk::Image(face));
    Gtk::Label *labelTabHeader = 
	Gtk::manage(new class Gtk::Label(Glib::Markup::escape_text(title), true));

    Gtk::Image *imageTabClose=
	Gtk::manage(new class Gtk::Image(Gtk::StockID("gtk-close"), Gtk::IconSize(1)));

    Gtk::Button *buttonTabHeader = Gtk::manage(new class Gtk::Button());
    Gtk::HBox *hboxTabHeader = Gtk::manage(new class Gtk::HBox(false, 0));


    page->setTitleLabel(labelTabHeader);

    imageTabHeader->set_size_request(16,16);
    //labelTabHeader->set_line_wrap(true);
    labelTabHeader->set_use_markup(true);
    labelTabHeader->set_single_line_mode(true);

//    imageBTabHeader->set_size_request(16,16);
    buttonTabHeader->set_size_request(16,16);
    buttonTabHeader->set_relief(Gtk::RELIEF_NONE);
    buttonTabHeader->unset_flags(Gtk::CAN_FOCUS);

    buttonTabHeader->add(*imageTabClose);
    hboxTabHeader->set_size_request(-1,16);

    hboxTabHeader->pack_start(*imageTabHeader, Gtk::PACK_SHRINK, 0);
    hboxTabHeader->pack_start(*labelTabHeader, Gtk::PACK_EXPAND_WIDGET, 5);
    hboxTabHeader->pack_start(*buttonTabHeader, Gtk::PACK_SHRINK, 0);
    hboxTabHeader->unset_flags(Gtk::CAN_FOCUS);

    hboxTabHeader->show_all();
    int ret = notebookMsg->append_page(*page, *hboxTabHeader);
    notebookMsg->pages().back().set_tab_label_packing(false, false, Gtk::PACK_START);
    labelTabHeader->set_mnemonic_widget(*hboxTabHeader);
    this->show_all();

    buttonTabHeader->signal_clicked().connect( 
	    sigc::bind<MsgPage*>(
		sigc::mem_fun(*this,
		    &MsgWindow::on_buttonTabHeader_clicked ), 
		page), false);
    return ret;
}

void MsgWindow::beginRefreshMembersStatus()
{
    Gtk::Notebook_Helpers::PageList& list = notebookMsg->pages();
    for_each(list.begin(), list.end(), BeginRefreshMembersStatus());
}

void MsgWindow::on_buttonTabHeader_clicked(MsgPage* page)
{
    notebookMsg->remove_page(*page);    
    page->hide();
    ///page->clear();
    if (!notebookMsg->get_n_pages()) {
	this->hide();
    }

}


void MsgWindow::showPage(BuddyInfo& buddyInfo, bool isActive)
{

    Glib::RefPtr<Gdk::Pixbuf> face;

    if (buddyInfo.isCluster()) {
	face = getClusterFace15();
    } else {
	FriendInfo& friendinfo = static_cast<FriendInfo&>(buddyInfo);
	face = getPix15(friendinfo.getFace(), friendinfo.getStatus());
    }

    int num;
    MsgPage* page = buddyInfo.getMsgPage();
    assert(NULL != page);
    //    if (NULL == page) {
    //	page = new MsgPage(buddyInfo, session, gmm_data);
    //	buddyInfo.setMsgPage(page);
    //	num = addPage(face, buddyInfo.getNickname(), page);
    //	page->beginRefreshMembersStatus();
    //    } else {
    num = notebookMsg->page_num(*page);
    if (-1 == num) {
	if (buddyInfo.getNickname().empty())
	    num = addPage(face, "陌生人", page);
	else
	    num = addPage(face, buddyInfo.getNickname(), page);
	page->beginRefreshMembersStatus();
    }
    //    }
    if (isActive) {
	notebookMsg->set_current_page(num);
	this->raise();
    } else {
	page->setTitleColor(true);
    }
    // set_focus(*(page->getFocusWidget()));
}

void MsgWindow::hideMemberList()
{
    MsgPage* page = getCurrentPage();
    if (page) {
	page->hideMemberList();
    }
}

void MsgWindow::sendMessage()
{
    MsgPage* page = getCurrentPage();
    if (page) {
	page->sendMessage();
    }
}

void MsgWindow::showLog(int logoffset)
{
    MsgPage* page= getCurrentPage();
    if (page) {
    	page->showLog(logoffset);
    }
}
void MsgWindow::saveLog()
{
  string filename;
  Gtk::FileChooserDialog dialog(*this, "请选择保存的位置", Gtk::FILE_CHOOSER_ACTION_SAVE);
  Gtk::StockID stockidOK("gtk-ok");
  Gtk::StockID stockidCancel("gtk-cancel");
  dialog.add_button(stockidCancel, Gtk::RESPONSE_CANCEL);                                                      
  dialog.add_button(stockidOK, Gtk::RESPONSE_OK); 
  int result = dialog.run();
  //Handle the response:
  //处理返回值
  switch(result)
  {
    case(Gtk::RESPONSE_OK):
    {
      filename = dialog.get_filename();
      //Notice that it is a std::string, not a Glib::ustring.
      //注意是std::string，而不是Glib::ustring。
      break;
    }
    case(Gtk::RESPONSE_CANCEL):
    {
      //std::cout << "Cancel clicked." << std::endl;
      break;
    }
    default:
    {
      //std::cout << "Unexpected button clicked." << std::endl;
      break;
    }
  }
  if(result== Gtk::RESPONSE_OK)
  {
  	MsgPage* page=getCurrentPage();
    	if (page) {
    		page->saveLog(filename);
		}
  }
}

bool MsgWindow::on_delete_event(GdkEventAny *ev)
{
    Gtk::Notebook_Helpers::PageList& list = notebookMsg->pages();
    for_each(list.begin(), list.end(), ClearPage());
    list.erase(list.begin(), list.end());
    return Gtk::Window::on_delete_event(ev);
}


bool MsgWindow::on_key_press_event(GdkEventKey* ev)
{
    if (ev->type != GDK_KEY_PRESS) 
	return Gtk::Window::on_key_press_event(ev);

    if (ev->state & (GDK_CONTROL_MASK)) {
	switch (ev->keyval) {
	    case GDK_1:
	    case GDK_2:
	    case GDK_3:
	    case GDK_4:
	    case GDK_5:
	    case GDK_6:
	    case GDK_7:
	    case GDK_8:
	    case GDK_9:
		notebookMsg->set_current_page(ev->keyval - GDK_1);
		break;
	    case GDK_Tab:
		if (notebookMsg->get_current_page() + 1 == 
			notebookMsg->get_n_pages())
		    notebookMsg->set_current_page(0);
		else
		    notebookMsg->next_page();
		break;
	    case GDK_Left:
		notebookMsg->prev_page();
		break;
	    case GDK_Right:
		notebookMsg->next_page();
		break;
	    case GDK_L:
	    case GDK_l:
		getCurrentPage()->clear();
		break;
	    default:
		return Gtk::Window::on_key_press_event(ev);
	}
	return true;
    } else {
	MsgPage* page;
	switch(ev->keyval) {
	    case GDK_Escape: 
		page = getCurrentPage();
		if (page)
		    on_buttonTabHeader_clicked(page);
		break;
	    case GDK_Return: 
	    case GDK_KP_Enter:
		page = getCurrentPage();
		if (page)
		    page->sendMessage();
		break;
	    default:
		return Gtk::Window::on_key_press_event(ev);
	}
    }
    return  true;
}


